﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TFSTools.TFSLibrary
{
    public abstract class TFSServerEntityCollection<T> : IList<T> where T : TFSServerEntity
    {
        private List<T> internalList;
        private ITFSConnection tfsConnection;

        protected TFSServerEntityCollection(ITFSConnection connection)
        {
            this.tfsConnection = connection;
            this.internalList = new List<T>();
        }

        protected TFSServerEntityCollection(ITFSConnection connection, IList<T> list)
        {
            this.tfsConnection = connection;

            if (list != null)
            {
                foreach (var entity in list)
                {
                    this.ValidateEntity(entity);
                }
            }

            if (list is List<T>)
            {
                this.internalList = (List<T>)list;
            }
            else
            {
                this.internalList = list.ToList();
            }
        }

        protected TFSServerEntityCollection(ITFSConnection connection, int capacity)
        {
            this.tfsConnection = connection;
            this.internalList = new List<T>(capacity);
        }

        internal virtual void ValidateEntity(T entity)
        {
            if (entity.Connection != this.tfsConnection)
            {
                throw new InvalidOperationException(string.Format("This {0} does not belong to the server connection associated with this collection.", entity.GetType().Name));
            }
        }

        /// <summary>
        /// Gets the TFSConnection object.
        /// </summary>
        /// <value>The TFSConnection object.</value>
        public ITFSConnection Connection { get { return this.tfsConnection; } }

        public int IndexOf(T item)
        {
            return this.internalList.IndexOf(item);
        }

        public void Insert(int index, T item)
        {
            this.internalList.Insert(index, item);
        }

        public void RemoveAt(int index)
        {
            this.internalList.RemoveAt(index);
        }

        public T this[int index]
        {
            get
            {
                return this.internalList[index];
            }

            set
            {
                this.ValidateEntity(value);
                this.internalList[index] = value;
            }
        }

        public void Add(T item)
        {
            this.ValidateEntity(item);
            this.internalList.Add(item);
        }

        public void Clear()
        {
            this.internalList.Clear();
        }

        public bool Contains(T item)
        {
            return this.internalList.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            this.internalList.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return this.internalList.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public bool Remove(T item)
        {
            return this.internalList.Remove(item);
        }

        public IEnumerator<T> GetEnumerator()
        {
            return this.internalList.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.internalList.GetEnumerator();
        }
    }
}
